<?php
/**
 * Created by PhpStorm.
 * User: zhongyongbiao
 * Date: 2018/10/26
 * Time: 下午12:49
 */

namespace App\Utility\Abst;

use App\Utility\Pub;
use App\Utility\Code;
use App\Cache\Session;
use EasySwoole\EasySwoole\Config;

abstract class Controller extends \EasySwoole\Http\AbstractInterface\Controller
{
    public function index()
    {
        // TODO: Implement index() method.
        $this->actionNotFound();
    }

    protected function actionNotFound(?string $action): void
    {
        // TODO: Change the autogenerated stub
        $this->writeJson(Code::NOT_FOUND);
    }

    private function getDebugData(): array
    {
        // 从请求里获取之前增加的时间戳
        $reqTime = $this->request()->getAttribute('request_time');
        // 计算一下运行时间
        $runtime = round(microtime(true) - $reqTime, 6) . 's';
        // 获取用户IP地址
        $ip = $this->request()->getAttribute('remote_ip');
        // 拼接日志内容
        $data = ['now' => Pub::udate(), 'ip' => $ip, 'runtime' => $runtime,
            'uri' => $this->request()->getUri()->__toString()];
        $userAgent = $this->request()->getHeader('user-agent');
        if (is_array($userAgent) && count($userAgent) > 0) {
            $data['user_agent'] = $userAgent[0];
        }
        return $data;
    }

    protected function writeJson($statusCode = 200, $data = null, $msg = null)
    {
        if (!$this->response()->isEndResponse()) {
            $json = ['code' => $statusCode, 'msg' => is_null($msg) ? Code::getReasonPhrase($statusCode) : $msg];
            if (!is_null($data)) {
                $json['data'] = $data;
            }
            if (Pub::isDev() || $this->request()->getRequestParam('debug') == 'on') {
                $json['debug'] = $this->getDebugData();
            }
            $this->response()->write(json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
            $this->response()->withHeader('Content-type', 'application/json;charset=utf-8');
            $this->response()->withStatus($statusCode);
            $this->response()->end();
            return true;
        } else {
            return false;
        }
    }

    protected function checkLogin(): ?int
    {
        $sid = $this->request()->getRequestParam('sess_token');
        $userInfo = (new Session())->getData($sid, 'userinfo');
        return isset($userInfo['userid']) ? intval($userInfo['userid']) : null;
    }

    /**
     * 简单的检验token封装，要求参数名必须是utime和token，规则是base64_encode(md5(utime.token_key))
     * @return int
     */
    protected function checkMd5Token(): int
    {
        $now = time();
        $utime = $this->request()->getRequestParam('utime');
        $sign = $this->request()->getRequestParam('sign');
        if (!isset($utime) || !isset($sign) || $utime > $now) {
            return Code::SIGN_INVAL;
        }
        $token = Config::getInstance()->getConf('app.token');
        if (($now - $utime) > $token['timeout']) {
            return Code::TOKEN_TIMEOUT;
        }

        if ($sign != base64_encode(md5($utime . $token['key']))) {
            return Code::SIGN_INVAL;
        }
        return Code::OK;
    }
}